package com.ly.heart.service.impl;

import java.util.List;
import java.util.Optional;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ly.common.PageParam;
import com.ly.common.core.domain.AjaxResult;
import com.ly.common.core.domain.entity.SysDept;
import com.ly.common.core.domain.entity.SysUser;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.StringUtils;
import com.ly.common.utils.erp.ConstUtil;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.heart.domain.*;
import com.ly.heart.domain.dto.KingInvoicePayableOtherDto;
import com.ly.heart.domain.dto.StartProcessDto;
import com.ly.common.core.domain.ActCurrentTaskVo;
import com.ly.heart.domain.vo.KingInvoicePayableOtherVo;
import com.ly.heart.mapper.KingInvoicePayableOtherMapper;
import com.ly.heart.service.*;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.system.service.ISysDeptService;
import com.ly.system.service.ISysUserService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 金蝶-财务-其他应付单Service业务层处理
 *
 * @author wutao
 * @date 2024-07-19
 */
@Service
public class KingInvoicePayableOtherServiceImpl extends ServiceImpl<KingInvoicePayableOtherMapper, KingInvoicePayableOtherEntity> implements IKingInvoicePayableOtherService {

    @Resource
    private KingInvoicePayableOtherMapper kingInvoicePayableOtherEntityMapper;
    @Resource
    private IKingInvoicePayableReceivableOtherDetailService iKingInvoicePayableReceivableOtherDetailService;
    @Resource
    private IActModelService iActModelService;
    @Resource
    private ICustomerService iCustomerService;
    @Resource
    private ISupplierService iSupplierService;
    @Resource
    private ISysDeptService iSysDeptService;
    @Resource
    private ISysUserService iSysUserService;
    @Resource
    private IKingBaseTransactionsCompanyService iKingBaseTransactionsCompanyService;
    @Resource
    private IActTaskCommentService iActTaskCommentService;

    /**
     * 查询金蝶-财务-其他应付单
     *
     * @param id 金蝶-财务-其他应付单ID
     * @return 金蝶-财务-其他应付单
     */
    @Override
    public KingInvoicePayableOtherVo selectKingInvoicePayableOtherEntityById ( String id ) {
        KingInvoicePayableOtherEntity payableOtherEntity = kingInvoicePayableOtherEntityMapper.selectKingInvoicePayableOtherEntityById ( id );
        String transactionCompanyName = getCompanyName ( payableOtherEntity.getTransactionCompanyType (), payableOtherEntity.getTransactionCompanyId () );
        payableOtherEntity.setTransactionCompanyName ( transactionCompanyName );
        KingInvoicePayableReceivableOtherDetailEntity payableReceivableOtherDetailEntity = new KingInvoicePayableReceivableOtherDetailEntity ();
        payableReceivableOtherDetailEntity.setRelationOtherId ( id );
        List<KingInvoicePayableReceivableOtherDetailEntity> kingInvoicePayableReceivableOtherDetailEntities = iKingInvoicePayableReceivableOtherDetailService.selectKingInvoicePayableReceivableOtherDetailEntityList ( payableReceivableOtherDetailEntity );
        KingInvoicePayableOtherVo vo = new KingInvoicePayableOtherVo ();
        vo.setKingInvoicePayableOtherEntity ( payableOtherEntity ).setKingInvoicePayableReceivableOtherDetailEntities ( kingInvoicePayableReceivableOtherDetailEntities );
        return vo;
    }

    /**
     * 查询金蝶-财务-其他应付单列表
     *
     * @param kingInvoicePayableOtherEntity 金蝶-财务-其他应付单
     * @return 金蝶-财务-其他应付单
     */
    @Override
    public List<KingInvoicePayableOtherEntity> selectKingInvoicePayableOtherEntityList ( KingInvoicePayableOtherEntity kingInvoicePayableOtherEntity ) {
        kingInvoicePayableOtherEntity.setIsUsed ( ConstUtil.IS_USED_YES );
        kingInvoicePayableOtherEntity.setPage ( ( kingInvoicePayableOtherEntity.getPage () - 1 ) * kingInvoicePayableOtherEntity.getLimit () );
        List<KingInvoicePayableOtherEntity> kingInvoicePayableOtherEntities = kingInvoicePayableOtherEntityMapper.selectKingInvoicePayableOtherEntityList ( kingInvoicePayableOtherEntity );
        kingInvoicePayableOtherEntities.forEach ( payableOther -> {
            if ( StringUtils.isNotBlank ( payableOther.getTransactionCompanyId () ) ) {
                String transactionCompanyName = getCompanyName ( payableOther.getTransactionCompanyType (), payableOther.getTransactionCompanyId () );
                payableOther.setTransactionCompanyName ( transactionCompanyName );
                //处理最后一个审批人
                ActTaskCommentEntity actTaskCommentEntity = iActTaskCommentService.queryLastComment ( payableOther.getInstanceId () );
                if ( actTaskCommentEntity != null ) {
                    payableOther.setApprovedUser ( actTaskCommentEntity.getApprovedUser () );
                    payableOther.setApprovedRemark ( actTaskCommentEntity.getRemark () );
                }
                //任务信息
                ActCurrentTaskVo currentTaskVo = iActModelService.getCurrentTaskByInstanceId ( payableOther.getInstanceId () );
                Optional.ofNullable ( currentTaskVo ).ifPresent ( currentTask -> {
                    payableOther.setCurrentTask ( currentTask );
                } );
            }
        } );
        return kingInvoicePayableOtherEntities;
    }

    @Override
    public Integer queryCount ( KingInvoicePayableOtherEntity kingInvoicePayableOtherEntity ) {
        Integer count = kingInvoicePayableOtherEntityMapper.queryCount ( kingInvoicePayableOtherEntity );
        return count;
    }

    /**
     * 通过Id查询关联对象信息
     *
     * @param id
     * @return
     */
    @Override
    public KingInvoicePayableOtherEntity querySingleById ( String id ) {
        KingInvoicePayableOtherEntity payableOtherEntity = kingInvoicePayableOtherEntityMapper.querySingleById ( id );
        return payableOtherEntity;
    }

    /**
     * 新增金蝶-财务-其他应付单
     *
     * @param kingInvoicePayableOtherDto 金蝶-财务-其他应付单
     * @return 结果
     */
    @Override
    public AjaxResult draft ( KingInvoicePayableOtherDto kingInvoicePayableOtherDto ) {
        KingInvoicePayableOtherEntity kingInvoicePayableOtherEntity = kingInvoicePayableOtherDto.getKingInvoicePayableOtherEntity ();
        int count = this.count ();
        kingInvoicePayableOtherEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
        kingInvoicePayableOtherEntity.setDocNo ( "QTYFD".concat ( String.format ( "%08d", count ) ) );
        kingInvoicePayableOtherEntity.setCreateTime ( DateUtils.getNowDate () );
        kingInvoicePayableOtherEntity.setDeptId ( CurrentUserUtil.getCompanyId () );
        kingInvoicePayableOtherEntity.setCreateBy ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
        kingInvoicePayableOtherEntity.setPayDeptId ( CurrentUserUtil.getCompanyId () );
        kingInvoicePayableOtherEntity.setProcureCompanyId ( CurrentUserUtil.getCompanyId () );
        kingInvoicePayableOtherEntity.setSettlementDeptId ( CurrentUserUtil.getCompanyId () );
        updatePayableOtherDetail ( kingInvoicePayableOtherDto.getKingInvoicePayableReceivableOtherDetailEntities (), kingInvoicePayableOtherEntity.getId () );
        kingInvoicePayableOtherEntity.setState ( ConstUtil.STATE_IN_DRAFT );
        boolean save = this.save ( kingInvoicePayableOtherEntity );
        if ( ! save ) {
            throw new CustomException ( "新增其他应付单失败！" );
        }
        return AjaxResult.success ( "暂存其他应付单成功", kingInvoicePayableOtherEntity.getId () );
    }

    @Override
    public AjaxResult submit ( KingInvoicePayableOtherEntity kingInvoicePayableOtherEntity ) {
        if ( StringUtils.isBlank ( kingInvoicePayableOtherEntity.getId () ) ) {
            return AjaxResult.error ( "请先暂存该单据！" );
        }
        StartProcessDto startDto = new StartProcessDto ().
                setBusinessId ( kingInvoicePayableOtherEntity.getId () ).
                setBusinessType ( kingInvoicePayableOtherEntity.getBusinessType () ).setModelId ( kingInvoicePayableOtherEntity.getModelId () ).
                setBusinessName ( "其他应付单_".concat ( kingInvoicePayableOtherEntity.getId () ) );
        String instanceId = iActModelService.startProcess ( startDto );
        boolean update = this.update ( new LambdaUpdateWrapper<KingInvoicePayableOtherEntity> ().
                set ( KingInvoicePayableOtherEntity :: getInstanceId, instanceId ).
                set ( KingInvoicePayableOtherEntity :: getState, ConstUtil.STATE_IN_PROCESS ).
                eq ( KingInvoicePayableOtherEntity :: getId, kingInvoicePayableOtherEntity.getId () ) );
        if ( ! update ) {
            throw new CustomException ( "提交其他应付单失败！" );
        }
        return AjaxResult.success ();
    }

    /**
     * 修改金蝶-财务-其他应付单
     *
     * @param kingInvoicePayableOtherDto 金蝶-财务-其他应付单
     * @return 结果
     */
    @Override
    public AjaxResult updateKingInvoicePayableOtherEntity ( KingInvoicePayableOtherDto kingInvoicePayableOtherDto ) {
        KingInvoicePayableOtherEntity kingInvoicePayableOtherEntity = kingInvoicePayableOtherDto.getKingInvoicePayableOtherEntity ();
        kingInvoicePayableOtherEntity.setUpdateTime ( DateUtils.getNowDate () );
        kingInvoicePayableOtherEntity.setUpdateBy ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
        updatePayableOtherDetail ( kingInvoicePayableOtherDto.getKingInvoicePayableReceivableOtherDetailEntities (), kingInvoicePayableOtherEntity.getId () );
        boolean b = this.updateById ( kingInvoicePayableOtherEntity );
        if ( ! b ) {
            throw new CustomException ( "修改其他应付单失败！" );
        }
        return AjaxResult.success ();
    }

    /**
     * 批量删除金蝶-财务-其他应付单
     *
     * @param ids 需要删除的金蝶-财务-其他应付单ID
     * @return 结果
     */
    @Override
    public AjaxResult deleteKingInvoicePayableOtherEntityByIds ( String[] ids ) {
        boolean update = this.update ( new LambdaUpdateWrapper<KingInvoicePayableOtherEntity> ().
                set ( KingInvoicePayableOtherEntity :: getIsUsed, ConstUtil.IS_USED_NO ).
                in ( KingInvoicePayableOtherEntity :: getId, ids ) );
        if ( ! update ) {
            throw new CustomException ( "删除其他应付单失败！" );
        }
        return AjaxResult.success ();
    }

    /**
     * 付款单选择其他应付单
     *
     * @param kingInvoicePayableOtherEntity
     * @return
     */
    @Override
    public AjaxResult queryList ( KingInvoicePayableOtherEntity kingInvoicePayableOtherEntity ) {
        kingInvoicePayableOtherEntity.setPage ( ( kingInvoicePayableOtherEntity.getPage () - 1 ) * kingInvoicePayableOtherEntity.getLimit () );
        kingInvoicePayableOtherEntity.setIsUsed ( ConstUtil.IS_USED_YES );
        kingInvoicePayableOtherEntity.setState ( ConstUtil.STATE_FINISH );
        List<KingInvoicePayableOtherEntity> kingInvoicePayableOtherEntities = kingInvoicePayableOtherEntityMapper.selectKingInvoicePayableOtherEntityList ( kingInvoicePayableOtherEntity );
        kingInvoicePayableOtherEntities.forEach ( otherDetail -> {
            String transactionCompanyName = getCompanyName ( otherDetail.getTransactionCompanyType (), otherDetail.getTransactionCompanyId () );
            otherDetail.setTransactionCompanyName ( transactionCompanyName );
        } );
        Integer integer = kingInvoicePayableOtherEntityMapper.queryCount ( kingInvoicePayableOtherEntity );
        PageParam p = new PageParam ();
        p.setRecords ( kingInvoicePayableOtherEntities ).setTotal ( integer );
        return AjaxResult.success ( p );
    }

    private void updatePayableOtherDetail ( List<KingInvoicePayableReceivableOtherDetailEntity> payableReceivableOtherDetailEntities, String relationId ) {
        if ( ! CollectionUtils.isEmpty ( payableReceivableOtherDetailEntities ) ) {
            iKingInvoicePayableReceivableOtherDetailService.remove ( new LambdaUpdateWrapper<KingInvoicePayableReceivableOtherDetailEntity> ().
                    eq ( KingInvoicePayableReceivableOtherDetailEntity :: getRelationOtherId, relationId ).
                    eq ( KingInvoicePayableReceivableOtherDetailEntity :: getType, 1 ) );
            payableReceivableOtherDetailEntities.forEach ( detail -> {
                detail.setRelationOtherId ( relationId );
                detail.setType ( 1 ); // 其他应付单
                iKingInvoicePayableReceivableOtherDetailService.insertKingInvoicePayableReceivableOtherDetailEntity ( detail );
            } );
        }
    }


    /**
     * 根据往来单位类型，获取往来单位和付款单位
     *
     * @param companyType：单位类型，根据往来单位或付款单位的类型魔法值
     * @param companyId：单位Id，根据单位类型，选择的具体单位Id
     * @return
     */
    private String getCompanyName ( String companyType, String companyId ) {
        if ( StringUtils.isBlank ( companyType ) || StringUtils.isBlank ( companyId ) ) {
            return "";
        }
        String transactionCompany = "";
        switch ( companyType ) {
            case "BD_Customer":
                CustomerEntity customerEntity = iCustomerService.getById ( companyId );
                transactionCompany = customerEntity.getCustomerName ();
                break;
            case "BD_Supplier":
                SupplierEntity supplierEntity = iSupplierService.getById ( companyId );
                transactionCompany = supplierEntity.getSupplierName ();
                break;
            case "BD_Department":
                SysDept sysDept = iSysDeptService.getById ( companyId );
                transactionCompany = sysDept.getDeptName ();
                break;
            case "BD_Empinfo":
                SysUser sysUser = iSysUserService.getById ( companyId );
                transactionCompany = sysUser.getNickName ();
                break;
            case "FIN_OTHERS":
                KingBaseTransactionsCompanyEntity transactionsCompanyEntity = iKingBaseTransactionsCompanyService.getById ( companyId );
                transactionCompany = transactionsCompanyEntity.getTitle ();
                break;
        }
        return transactionCompany;
    }
}
